﻿using System;
using System.Data;
using org.se.fs.presenter.Library;
using org.se.fs.presenter.Task.Template;

namespace org.se.fs.presenter.View.Template
{
    public abstract class SubMenu
    {
        public event FormEvent.FormEventHandler OnAdd;
        public event FormEvent.FormEventHandler OnModify;
        public event FormEvent.FormEventHandler OnValidate;
        public event FormEvent.FormEventHandler OnError;
        protected IView.Template.IFormSubMenu FormView;
        protected string Name;
        protected Crud Task;
        protected DataRow Data;

        public virtual void Initialize()
        {
            Task.OnFetch += TaskOnFetch;
            Task.OnInsert += TaskOnInsert;
            Task.OnUpdate += TaskOnUpdate;
            FormView.SetLabel((IsNewData() ? @"Create New " : @"Modify ") + Name);
            FormView.ButtonAddVisible(IsNewData());
            FormView.ButtonUpdateVisible(!IsNewData());
        }

        protected void TriggerAdd(FormEvent e)
        {
            if (OnAdd != null)
                OnAdd(this, e);
        }

        protected void TriggerModify(FormEvent e)
        {
            if (OnModify != null)
                OnModify(this, e);
        }

        protected void TriggerValidate(FormEvent e)
        {
            if (OnValidate != null)
                OnValidate(this, e);
        }

        protected void TriggerError(FormEvent e)
        {
            if (OnError != null)
                OnError(this, e);
        }

        protected virtual void DomainPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            //-- if you want to process data when item value was changed.
            switch (e.PropertyName)
            {
                case "":
                    //-- code goes here
                    break;
            }     
        }
  
        protected virtual void TaskOnInsert(object source, FormEvent e)
        {
            FormView.ButtonAddEnable(true);
            TriggerAdd(new FormEvent(e.IsSuccess) { Exception = e.Exception, Value = e.Value });
        }

        protected virtual void TaskOnUpdate(object source, FormEvent e)
        {
            FormView.ButtonUpdateEnable(true);
            TriggerModify(new FormEvent(e.IsSuccess) { Exception = e.Exception, Value = e.Value });
        }
      
        protected virtual void TaskOnFetch(object source, FormEvent e) { }

        public virtual void Add()
        {
            if (!Validate())
                return;

            FormView.ButtonAddEnable(false);
            FillData();
            Task.Insert(Data);
        }

        public virtual void Modify()
        {
            if (!Validate())
                return;

            FormView.ButtonUpdateEnable(false);
            FillData();
            Task.Update(Data);
        }

        protected virtual bool Validate()
        {
            return true;
        }

        public void SetData(DataRow data)
        {
            Data = data;

            if (IsNewData()) 
                return;

            SetUi();
        }

        protected virtual void SetUi() { }

        protected UInt64 ToUInt64(object data)
        {
            try { return Convert.ToUInt64(data); }
            catch (Exception) { return 0; }
        }

        protected bool IsNewData()
        {
            return string.IsNullOrEmpty(Data[0].ToString());
        }

        protected virtual void FillData() { }

        protected int? GetIndexByDataTable(DataTable data, string sourceColumn, object value)
        {
            for (var i = 0; i < data.Rows.Count; i++)
            {
                if (!data.Rows[i][sourceColumn].ToString().Equals(value.ToString())) continue;
                return i;
            }
            return null;
        }
    }
}
